#include <utility>
#include <limits>
#include <list>
#include "Test.h"
#include "model1/Test3.h"
#include "model1/Test4.h"
#include "model1/Test5.h"
#include "model1/Test7.h"
#include "model1/Test9.h"
#include "model1/LeetCode.h"
#include "model1/Test11.h"
#include <fstream>
#include <istream>
#include <iostream>
#include <ctime>
#include <memory>
#include <stack>
#include <unordered_map>
#include <map>
#include <set>
#include <queue>
#include <vector>
#include <thread>
#include "model1/Test8.h"
#include "windows.h"
#include <future>
#include <algorithm>
#include "model1/Test10.h"
#include <boost/json/src.hpp>
#include <boost/optional.hpp>
#include <boost/array.hpp>
#include "model1/Test12.h"
#include "math.h"

struct TestData {
private:
    int age;
    char *aname;

public:

    TestData() = default;

    TestData(int age, char name[]) : age(age), aname(name) {
    }

    ~TestData() = default;

    void foo() {
        this->age++;
    }

    [[nodiscard]] int getAge() const {
        return this->age;
    }

    std::string getName() {
        return this->aname;
    }

    void foo2() {
        //静态变量在任何地方声明在真个程序执行中都是全局的 所以每次执行下面代码定义只会定义一次
        // 接下来的每次调用都会在这个静态变量上面累加
        static int c = 0;
        c++;
        std::cout << c;
    }

    TestData operator+(const TestData &left) {
        TestData t{};
        t.age = this->age + left.age;
        t.aname = this->aname;
        std::cout << &t;
        return t;
    }
};


void test1Foo1(char *c) {
    c[0] = '2';
    std::cout << c;
}


class Animal {
private:
    int age;
    char *name;

public:
    Animal() = default;

    Animal(int age, char ar[]) : age(age), name(ar) {};

    virtual void doSomeThing() = 0;
};

class Dog : public Animal {
private:
    int color;

public:
    Dog() = default;

    Dog(int color) : color(color), Animal(1, "dog") {}

    void doSomeThing() override {
        std::cout << "我是一条狗";
    }
};


class AbstractAction {

protected:
    int v;

protected:
    AbstractAction() = default;

public:

    virtual void doSomeThing() = 0;
};

class MyClass : public AbstractAction {

private:
    //mutable 修饰的可以在const 重新赋值
    mutable int a = 1;
    int b = 1;

public:
    MyClass() = default;

    void doSomeThing() override {
        std::cout << "可以说非常的牛逼";
    }

//    友元
    friend void goodMethod(MyClass *m) {
        std::cout << m->v;
    }

    //const函数表示不能重新赋值成员变量
    void foo() const {
    }
};

//extern 关键字 修饰 代表使用其他文件内的方法和字段 但是不能#include
extern void test4Foo1();

template<typename T>
// concept 代表是一个字面量意思就是表达式必须返回true或者false
concept is_number =  std::is_arithmetic_v<T>;
// requires 表达式代表是否是可以对表达式进行正常编译通过 通过true 不通过就是false
//https://blog.csdn.net/qq_42896106/article/details/125341828

template<typename T>
requires is_number<T>
void testTl(T t) {

}

class MyException : public std::exception {

public:
    MyException() = default;

    [[nodiscard]] const char *what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW override {
        return "wdnmd";
    }
};

template<typename T>
T sum(T t) {
    return t;
}

template<typename T, typename... Args>
T sum(T first, Args... args) {
    return first + sum(args...); // 递归展开
}

// TIP 要<b>Run</b>代码，请按 <shortcut actionId="Run"/> 或点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
int main() {
    system("chcp 65001");
    //数组指针
//    int ar[2][3] = {{1, 3, 5},
//                    {2, 4 ,6}};
// n维数组就是分配的一块连续内存
//    int  (*br)[3] = &ar[1];
//    cout << (*br)[1];
//  数组引用
//    int ar[1][3] = {{1, 2, 3}};
//    int (&a)[3] = ar[0];
//    cout << a[1];
// 数组指针移动
//    int ar[1][3] = {{1,3, 6}};
//    int (*ptr)[3] = &ar[0];
//    cout << *((*ptr) + 1);
// 指针数组
//    string cc = "";
//    TestData t1(1, cc), t2(2, cc);
//    TestData *ar[1][2] = {{&t1, &t2}};
//    for (const auto &item: ar)
//        cout << item->getAge();
// 指针数组中获取其中一个指针数组
//    Test t(1, "");
//    Test t2(3, "");
//    Test *ar[1][2] = {{&t, &t2}};
//    Test *(*vr)[2] = &ar[0];
//    string aa = "dwad";
//    auto (*a)(char *c) = test1Foo1;
//    a(aa.data());
//函数指针
//    string s = "";
//    void (*f1ptr)(char *) = test1Foo1;
//    void *ff = (void *) f1ptr;
//    f1ptr = reinterpret_cast<void (*)(char *)>(ff);
//    f1ptr(s.data());
// 指针数组 (类型是指针 的数组 )
//    string c = "dwadaw";
//    map<string, void *> m;
//    m["a"] = &c;
//    string *cc = reinterpret_cast<string*>(m["a"]);
//    cout << *cc;

//    Test2Struct2* ar[1][2] = {{&test2Data[0], &test2Data[1]}};
//    Test2Struct2* (*a)[2] = &ar[0];
//    cout << (*a)[1]->age;int
//    TS4 a[2] = {
//            {1,  "dwad"}
//    };
//    a[1] = {1, "dwad"};
//    cout << a[0].name;
// 继承和super, 和调用父构造
//    Test4Child t4("dwad");
//    Test4* t = &t4;
//    t->foo1();
//    cout << r;
// 多态
//    Animal *animalPtr = new Dog(1);
//    animalPtr->doSomeThing();
//    MyClass m;
//    m.doSomeThing();
// 动态内存分配
//    int *a = nullptr;
//    if (a = new int) {
//        *a = 2;
//        cout << *a;
//        delete a;
//    }
//    Test *t = nullptr;
//    if (t = new Test(1, "daw")) {
//        cout << t->p_name;
//        delete t;
//    }
//    tuple<int, int, int, int> t(1, 2, 3, 4);
//    cout << get<0>(t);
// ##是一个特殊符号对当参数传递为空时做一个填充作用
#define log(format, ...) { \
    auto _t = time(nullptr);\
    auto _tt = localtime(&_t); \
    std::string _sb = ""; \
    _sb.append(std::to_string(1900 + _tt->tm_year));\
    _sb.append(":");\
    _sb.append(std::to_string(1 + _tt->tm_mon));\
    _sb.append(":");\
    _sb.append(std::to_string(_tt->tm_mday));\
    _sb.append(" ");      \
    _sb.append(std::to_string(_tt->tm_hour));       \
    _sb.append(":");\
    _sb.append(std::to_string(_tt->tm_min));        \
    _sb.append(":");\
    _sb.append(std::to_string(_tt->tm_sec));\
    printf("%s==INFO %s %s [%s:%s:%d]", _sb.c_str(), format,  ##__VA_ARGS__, __FILE_NAME__, __FUNCTION__, __LINE__); \
}
//    log("dawd", "dawd");
//    Ns5::testTemplate();
//    Ns5::testTemplate(2);
//    const int a = 1;
    //const_cast将const转化成没有const修饰符的type指针
//    int *v = const_cast<int*>(&a);
//    const char *c = "dawd";
//    std::string s = "Dwad";
//    std::cout << s.length();
//    Ns5::Test6Struct3 s = {1, &c};
    //堆上分配 m是指针
//    auto m = new std::map<std::string, int>();
    // 站上分配 m2是对象
//    std::map<std::string, int> m2;
//    Test10 t, b;
//    int *c = t + b;
//    std::cout << *c;
//    signal(SIGINT, signalHandler);
//    while (true) {
//        抛出SIGINT 即程序中断信号 抛出信号即 中断程序
//        raise(SIGINT);
//        Sleep(1000);
//        std::cout << "sig >>";
//    }
//    int ar[] = {4, 5, 6};
//    std::cout << ar[getIndex(1, 2)];
//    const int aa = 1;
    //static_cast, dynamic_cast, 如果左边是引用右边可以是值 如果左边是指针那么右边就是 &引用
//    int &c = const_cast<int &>(aa);
//    int *c = const_cast<int *>(&aa);
//    std::vector<int> v1 = {1,3};
//    std::vector<int> v2 = {2};

//    std::cout << leetCode::test1(v1, v2);
#define  min(a, b) ((a > b) ? b : a)
#define concat(a, b) a##b
//    std::string s1 = "aab", p = "c*a*b";
//    std::cout << leetCode::test2(s1, p);
//    std::vector<std::vector<bool>> v(s1.size(), std::vector<bool>(p.size()));
//    v[0][0] = true;
//    v[s1.size() - 1][p.size() - 1] = true;
//    std::cout << v[0][0] << "\t" <<  v[s1.size() - 1][p.size() - 1] ;
// int k; 是C++中允许的创建方式 但是这里面不知道装的什么值 循环中会再次存在
//    test10Foo4(1); 隐式转化
//    int &&a = 1; 右值引用没有拷贝开销 const int &a = 1;
// 数组创建就是返回指针 指针拷贝的就是指针
//    int ar[2] = {1, 2};
//    std::cout << ar;
//    int *ar3 = ar;
//    std::cout << ar3;
//    Test11::Test11C4 *a = new Test11::Test11C5();
//    typeof 关键字和decltype 是一类 一个是C语言拓展一个是C++标准
//    typeof(a) c;
// 对象是否是属于这个类型 typeid返回某个类型和对象的typeinfo
//    if (typeid(a) == typeid(Test11::Test11C4 *)) {
//        std::cout << "?";
//    }

// https://blog.csdn.net/Ethan_Rich/article/details/153317302 左值和右值
//    变量权限转移， 将左值转化成右值
    T12::t12Foo6();
};